package com.newly.driver.sdk.device.video.service.impl.qiniu;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.newly.driver.sdk.device.video.constants.DeviceConstant;
import com.newly.driver.sdk.device.video.service.impl.AbstractCloud;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.qvs.DeviceManager;
import com.qiniu.qvs.StreamManager;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author gjm guan
 * @date 2021/10/19 11:44
 * @desc 七牛平台
 */
@Component
@Slf4j
public abstract class AbstractQiNiuCloud extends AbstractCloud {

    @Value("${device.qiniu.accessKey}")
    protected String accessKey;

    @Value("${device.qiniu.secretKey}")
    protected String secretKey;

    @Value("${device.qiniu.namespaceId}")
    protected String namespaceId;

    @Value("${device.qiniu.api.server.url}")
    protected String apiServer;

    @Value("${device.qiniu.api.publishIP}")
    protected String publishIP;

    @Value("${device.qiniu.api.playIP}")
    protected String playIP;


    /**
     * 七牛设备状态
     * （offline: 离线, online: 在线,notReg: 未注册, locked: 锁定）
     */
    public enum QiniuDeviceState {
        OFFLINE(0, "offline"),
        ONLINE(1, "online"),
        NOTREG(2, "notReg"),
        LOCKED(3, "locked");

        QiniuDeviceState(int key, String value) {
            this.key = key;
            this.value = value;
        }

        public static QiniuDeviceState getInstance(String value) {
            QiniuDeviceState[] values = QiniuDeviceState.values();
            for (QiniuDeviceState qiniuDeviceStatus : values) {
                if (qiniuDeviceStatus.getValue().equals(value)) {
                    return qiniuDeviceStatus;
                }
            }
            return null;
        }

        public int getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }

        private int key;
        private String value;
    }

    /**
     * 七牛云请求状态
     */
    public enum QiNiuRequestState {
        OK(200, "OK"), ERR(1, "ERR");

        QiNiuRequestState(int key, String value) {
            this.key = key;
            this.value = value;
        }

        public int getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }

        private int key;

        private String value;
    }


    protected Auth auth() {
        return Auth.create(accessKey, secretKey);
    }

    /**
     * 解析成byte数组
     *
     * @param response 响应数据
     * @return
     */
    protected String parseStr(Response response) {
        if (ObjectUtil.isEmpty(response)) {
            return null;
        }
        byte[] body = null;
        try {
            body = response.body();
            if (body != null) {
                return new String(body, 0, body.length);
            }
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解析成map
     *
     * @return JSONObject
     */
    protected JSONObject parseMap(Response response) {
        String bodyStr = parseStr(response);
        if (StrUtil.isBlank(bodyStr)) {
            return null;
        }
        return JSONUtil.parseObj(bodyStr);
    }

    /**
     * 获取设备管理对象
     */
    protected DeviceManager getDeviceManager() {
        return new DeviceManager(auth());
    }

    /**
     * 获取流管理对象
     */
    protected StreamManager getStreamManager() {
        return new StreamManager(auth());
    }

    /**
     * 查看设备类型，如果是nvr需要将设备id和通道id以_拼接
     *
     * @param deviceId  设备id
     * @param channelId 通道id
     * @return 流id
     */
    protected String handlerStreamId(String deviceId, String channelId) {
        DeviceConstant.DeviceType deviceType = super.queryDeviceType(deviceId);
        if (deviceType.getKey() == DeviceConstant.DeviceType.IPC.getKey()) {
            return deviceId;
        } else if (deviceType.getKey() == DeviceConstant.DeviceType.NVR.getKey()) {
            return deviceId + "_" + channelId;
        }
        return null;
    }

}
